<!DOCTYPE html>

<!-- SpringBoot集成Vue3接入主流三方支付平台 -->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 网页标签名称 -->
    <title>Mainstream payment platform</title>
    <!-- element-plus style -->
    <link rel="stylesheet" href="/el/index.css"/>
    <!-- vue v3.4.21 -->
    <script src="/vue/vue.global.js"></script>
    <!-- element-plus component library -->
    <script src="/el/index.full.js"></script>
    <!-- 国际化 -->
    <script src="/el/zh-cn.js"></script>
    <!-- element-plus icons -->
    <script src="/el/index.iife.min.js"></script>
    <!-- axios -->
    <script src="/axios/axios.min.js"></script>

    <!-- 模拟生成商品ID -->
    <script src="/js/snow-flake.js"></script>
</head>

<!-- 样式 -->
<style scoped>
    .art_title {
        margin-top: 68px;
        text-align: center;
        font-size: 48px;
        letter-spacing: 6px;
        font-weight: 600;
        background: -webkit-linear-gradient(315deg, #42d392 25%, #647eff);
        background-clip: text;
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
    }

    .tripartite-pay_storehouse {
        width: 1336px;
        height: 451px;
        top: 55%;
        left: 50%;
        margin-top: -201px;
        margin-left: -668px;
        text-align: left;
        position: fixed;
        /*position: absolute;*/
        z-index: 2;
        background: #fff;
        -webkit-border-radius: 12px;
        -moz-border-radius: 12px;
        border-radius: 12px;
        background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#f4f4f4));
        background-image: -webkit-linear-gradient(top, #ffffff, #f4f4f4);
        background-image: -moz-linear-gradient(top, #ffffff 0, #f4f4f4 100%);
        background-image: linear-gradient(-180deg, #ffffff, #f4f4f4);
        -webkit-box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1);
        box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1);
        pointer-events: all;
    }

    .tripartite_pay_logo > div {
        height: 150px;
        align-items: center;
        justify-content: center;
        display: flex;
    }

    .pay_tripartite_common {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 50px;
    }

    .first_line_div .pay_tripartite_common {
        padding: 35px;
    }

    /* 隐藏Loading时浏览器在body中添加的一个div */
    .el-loading-mask is-fullscreen {
        display: none;
    }
</style>

<!-- 网页主体 -->
<body>

<!-- 页面容器 -->
<div id="tripartitePay" style="width: 80%; margin: 0 auto">
    <div class="art_title">接入第三方主流支付平台示例</div>
    <div class="tripartite-pay_storehouse">
        <div class="tripartite_pay_logo">
            <!-- 第一行 -->
            <div class="first_line_div">
                <div class="pay_tripartite_common">
                    <el-button type="primary" link @click="tripartitePayUnifiedInterface('WeChat')">
                        <img style="width: 241px;" src="/images/logo/WeChat.png" alt="" srcset="">
                    </el-button>
                </div>
                <div class="pay_tripartite_common">
                    <el-button type="primary" link @click="tripartitePayUnifiedInterface('Alipay')">
                        <img style="width: 139px" src="/images/logo/Alipay.svg" alt="" srcset="">
                    </el-button>
                </div>
                <div class="pay_tripartite_common">
                    <el-button type="primary" link @click="tripartitePayUnifiedInterface('UnionPay')">
                        <img style="width: 224px;" src="/images/logo/UnionPay.png" alt="" srcset="">
                    </el-button>
                </div>
                <div class="pay_tripartite_common">
                    <el-button type="primary" link @click="tripartitePayUnifiedInterface('DxmPay')">
                        <img style="width: 264px;" src="/images/logo/DxmPay.png" alt="" srcset="">
                    </el-button>
                </div>
            </div>

            <!-- 第二行 -->
            <div class="second_line_div">
                <div class="pay_tripartite_common">
                    <el-button type="primary" link @click="tripartitePayUnifiedInterface('YunFlashPay')">
                        <img style="width: 174px;" src="/images/logo/YunFlashPay.png" alt="" srcset="">
                    </el-button>
                </div>
                <div class="pay_tripartite_common">
                    <el-button type="primary" link @click="tripartitePayUnifiedInterface('ICBC')">
                        <img style="width: 251px;" src="/images/logo/ICBC.png" alt="" srcset="">
                    </el-button>
                </div>
                <div class="pay_tripartite_common">
                    <el-button type="primary" link @click="tripartitePayUnifiedInterface('CMB')">
                        <img style="width: 149px" src="/images/logo/CMB.png" alt="" srcset="">
                    </el-button>
                </div>
                <div class="pay_tripartite_common">
                    <el-button type="primary" link @click="tripartitePayUnifiedInterface('PayPal')">
                        <img style="width: 194px;" src="/images/logo/PayPal.svg" alt="" srcset="">
                    </el-button>
                </div>
            </div>

            <!-- 第三行 -->
            <div class="third_line_div"></div>
        </div>
    </div>
</div>

<script type="application/javascript" charset="UTF-8">
    // 从vue里解构（导出）模块
    const {createApp, ref, reactive, toRefs} = Vue;
    // 创建应用实例
    const tripartitePay = Vue.createApp({
        /**
         * @Description 根组件选项
         */
        setup() {
            // 双向绑定的响应式数据对象
            const parameter = reactive({})

            /* 三方支付 */
            const tripartitePayUnifiedInterface = (val) => {
                if (null !== val && val !== '') {
                    // 开始加载，加载组件铺满整个屏幕
                    const redirectionLoading = ElementPlus.ElLoading.service({
                        // 是否显示动画
                        lock: true,
                        // 显示在加载图标下方的加载文案
                        text: '系统正在唤起 ' + val + ' 支付平台，请稍等...',
                        // 遮罩背景色
                        background: 'rgba(0, 0, 0, 0.7)',
                    })

                    // 生成商品ID，productId
                    const generatorSnowflake = new Snowflake().nextId();
                    // 发送请求
                    axios({
                        method: 'post',
                        url: '/tripartite/pay/entrance',
                        data: {
                            payType: val,
                            productId: generatorSnowflake
                        },
                    }).then(function (response) {
                        // 获取响应体
                        const result = response.data;
                        // 请求成功
                        paymentResults(result, val);
                        // 调用第三方支付接口成功在进行重定向页面
                        if (200 === result.code) {
                            // 转到相应支付页面，参数为：后端返回的数据对象，Map<String, Object> resultMap
                            redirectionTradePagePay(result.data);
                        }

                        // 关闭加载
                        redirectionLoading.close();
                        console.log(response);

                    }).catch(function (error) {
                        // 请求失败
                        ElementPlus.ElMessage({
                            message: '请求错误，' + val + ' 平台支付出现异常.',
                            type: 'error',
                            plain: true,
                        })
                        // 关闭加载
                        redirectionLoading.close();
                        console.log(error);
                    });
                } else {
                    ElementPlus.ElMessage({
                        message: 'Unknown，未识别第三方支付平台.',
                        type: 'error',
                        plain: true,
                    })
                }
            }

            /* 重定向到相应支付页面 */
            const redirectionTradePagePay = (result) => {
                const payType = result.payType;
                if ('' !== payType && null !== payType) {
                    switch (payType) {
                        case "Alipay":
                            // 在浏览器执行支付返回的form表单
                            document.write(result.actionUrl);
                            break;

                        case "WeChat":
                            console.log('重定向支付页面，' + payType + ' 支付平台页面.');
                            break;

                        case "ICBC":
                            console.log('重定向支付页面，' + payType + ' 支付平台页面.');
                            break;

                        default:
                            ElementPlus.ElMessage({
                                message: 'Unknown，重定向到 ' + payType + ' 支付平台出现异常.',
                                type: 'error',
                                plain: true,
                            })
                            break;
                    }
                }
            }

            /* 支付结果 */
            const paymentResults = (result, val) => {
                if (200 === result.code) {
                    const returnMsg = result.returnMsg;
                    if (null !== returnMsg && '' !== returnMsg) {
                        ElementPlus.ElMessage({
                            message: '成功，' + returnMsg,
                            type: 'success',
                            plain: true,
                        })
                    } else {
                        ElementPlus.ElMessage({
                            message: '成功，' + val + ' 平台支付成功.',
                            type: 'success',
                            plain: true,
                        })
                    }
                } else {
                    ElementPlus.ElMessage({
                        message: '错误，' + result.returnMsg,
                        type: 'error',
                        plain: true,
                    })
                }
            }

            /* 将响应式对象中的所有属性转为单独的响应式数据，如：const bpmnName = ref(""); */
            const dataRef = toRefs(parameter);
            return {
                ...dataRef,
                tripartitePayUnifiedInterface,
                paymentResults,
                redirectionTradePagePay,
            };
        },
    });

    // 全局注册所有图标
    for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
        tripartitePay.component(key, component)
    }
    // 引入element-plus，{ locale: ElementPlusLocaleZhCn }引入国际化中文， 挂载VueRouter
    tripartitePay.use(ElementPlus, {locale: ElementPlusLocaleZhCn});
    // 挂载应用，.mount()方法应该始终在整个应用配置和资源注册完成后被调用
    tripartitePay.mount("#tripartitePay");
</script>

</body>
</html>